package com.gylang.im.passport.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gylang.commons.util.GResultUtils;
import com.gylang.commons.util.Md5Utils;
import com.gylang.commons.valid.Group1;
import com.gylang.commons.valid.Group2;
import com.gylang.commons.valid.Group3;
import com.gylang.commons.vo.BaseResultVO;
import com.gylang.im.core.constant.SystemConstants;
import com.gylang.im.core.enums.AuthEnums;
import com.gylang.im.core.enums.ResultEnum;
import com.gylang.im.user.constant.SsoConstant;
import com.gylang.im.user.dto.MemberUserDTO;
import com.gylang.im.user.dto.PtUserDTO;
import com.gylang.im.user.entity.PtUserDO;
import com.gylang.im.user.service.PtUserService;
import com.gylang.user.context.constant.RoleTypeEnums;
import com.gylang.user.context.domain.UserContextDTO;
import com.gylang.user.context.util.UserContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.validation.groups.Default;

/**
 * 会员
 *
 * @author gylang
 * data 2020/9/3
 * @version v0.0.1
 */
@RequestMapping("common")
public class PtUserController {

    @Autowired
    private PtUserService ptUserService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @PostMapping("login")
    public BaseResultVO login(@RequestBody PtUserDTO ptUserDTO) {
        ResultEnum.PARAMS_ERROR.asTrue(() -> {
            // 用户名，邮箱和手机号不能同时为空
            boolean userNumNotAllEmpty = !ObjectUtil.isAllEmpty(ptUserDTO.getEmail(), ptUserDTO.getTel(), ptUserDTO.getTel());
            //并且密码不能为空
            boolean userAndPasswordNotEmpty = userNumNotAllEmpty && StrUtil.isNotBlank(ptUserDTO.getPassword());
            //对手机号，用户名 邮箱进行校验
            validateUserInfo(ptUserDTO);
            return userAndPasswordNotEmpty;
        });
        //用户信息查询
        QueryWrapper<PtUserDO> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotEmpty(ptUserDTO.getTel()), "tel", ptUserDTO.getTel());
        wrapper.eq(StrUtil.isNotEmpty(ptUserDTO.getEmail()), "email", ptUserDTO.getEmail());
        wrapper.eq(StrUtil.isNotEmpty(ptUserDTO.getUsername()), "username", ptUserDTO.getUsername());
        PtUserDO ptUserDO = ptUserService.getOne(wrapper);
        //判断账户是否存在 密码是否正确
        AuthEnums.USER_NOT_FOUND.asNotEmpty(ptUserDO);
        boolean passwordCorrect = Md5Utils.md5(ptUserDTO.getPassword(), ptUserDO.getSalt()).equals(ptUserDO.getPassword());
        AuthEnums.USERNAME_PASSWORD_ERROR.asTrue(passwordCorrect);
        // 存储用户上下文
        UserContextDTO userContextDTO = UserContextDTO.builder()
                .uid(ptUserDO.getId())
                .nickName(ptUserDO.getNickname())
                .username(ptUserDO.getUsername())
                .build();
        //存储角色
        userContextDTO.addRole(RoleTypeEnums.COMMON_USER.buildRole());
        String accessToken = UUID.randomUUID().toString();
        UserContextUtils.pushUserContext(accessToken, userContextDTO);
        // 返回accessToken
        // todo 发送消息 缓存用户其他信息 如用户扩展 订单等
        return GResultUtils.setData(accessToken);
    }

    /**
     * 邮箱注册
     *
     * @param memberUserDTO 邮箱注册入参
     * @return 注册结果
     */
    @PostMapping("/register/byEmail")
    public BaseResultVO register(MemberUserDTO memberUserDTO) {
        // Group2 指定邮箱校验 和默认需要校验
        ResultEnum.PARAMS_ERROR.valid(memberUserDTO, Default.class, Group2.class);
        //校验通过 缓存数据 发送邮件
        String salt = UUID.fastUUID().toString();
        String password = Md5Utils.md5(memberUserDTO.getPassword(), salt);
        // 存储到数据库
        PtUserDO ptUserDO = PtUserDO.builder()
                .isDelete(SystemConstants.STATUS_NOT_DELETE)
                .status(SsoConstant.WAITING_TO_EMAIL_VERIFY)
                .nickname(memberUserDTO.getName())
                .password(password)
                .salt(salt)
                .build();
        ptUserService.save(ptUserDO);
        //todo 发送邮件
        return GResultUtils.setData("请登录邮箱激活");
    }


    /**
     * 用户登录账户条件判断
     * com.gylang.mall.api.validate.Group1 用户名条件
     * com.gylang.mall.api.validate.Group2 邮箱
     * com.gylang.mall.api.validate.Group3 手机号码
     *
     * @param ptUserDTO 登录入参
     */
    private void validateUserInfo(PtUserDTO ptUserDTO) {
        if (StrUtil.isNotEmpty(ptUserDTO.getUsername())) {
            ResultEnum.PARAMS_ERROR.valid(ptUserDTO, Group1.class);
        }
        if (StrUtil.isNotEmpty(ptUserDTO.getEmail())) {
            ResultEnum.PARAMS_ERROR.valid(ptUserDTO, Group2.class);
        }
        if (StrUtil.isNotEmpty(ptUserDTO.getTel())) {
            ResultEnum.PARAMS_ERROR.valid(ptUserDTO, Group3.class);
        }
    }
}
